<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/10/18
 * Time: 16:35
 */

namespace common\business;

use common\consts\CommonResources;
use Yii;
use common\helpers\StringUtil;
use common\models\qywx\Department;
use common\models\qywx\QywxUser;
use common\result\ActionResult;
use linslin\yii2\curl\Curl;
use yii\base\UserException;
use yii\helpers\Json;

class QywxApiService
{
    protected $baseUrl = 'https://qyapi.weixin.qq.com/cgi-bin';

    /**
     * 根据code得到UserId
     * https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
     * @param $code
     * @return \common\models\qywx\QywxUser
     * @throws UserException
     */
    public function getUserInfoByCode($code){
        $url = $this->baseUrl . '/user/getuserinfo';

        $curl = new Curl();
        $curl->setGetParams([
            'access_token' => QywxHelper::getAccessTokenVal(),
            'code' => $code,
        ]);
        $curl->setHeaders([
            'Content-Type' => 'application/json; charset=UTF-8',
        ]);
//        must add this line
//         http://blog.csdn.net/kobejayandy/article/details/44761913
        $curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
        $response = $curl->get($url);

        if ($curl->errorCode === null) {
//                返回结果：
//{
//    "UserId":"USERID",
//}
//                出错返回示例：
//
//{
//    "errcode": 40029,
//   "errmsg": "invalid code"
//}
            $responseArr = Json::decode($response, true);
            if ($responseArr['errcode'] != null){
                $exceptionStr = sprintf('errcode: %s, errmsg: %s', $responseArr['errcode'], $responseArr['errmsg']);
                throw new UserException($exceptionStr);
            }

            $userId = $responseArr['UserId'];
            return $this->getUserInfoByUserId($userId);
        } else {
            $exceptionStr = sprintf('errorCode: %s, errorText: %s', $curl->errorCode, $curl->errorText);
            throw new UserException($exceptionStr);
        }
    }

    /**
     * 根据code得到UserId
     * https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&userid=USERID
     * @param $userId
     * @return \common\models\qywx\QywxUser
     * @throws UserException
     */
    public function getUserInfoByUserId($userId){
        $url = $this->baseUrl . '/user/get';

        $curl = new Curl();
        $curl->setGetParams([
            'access_token' => QywxHelper::getAccessTokenVal(),
            'userid' => $userId,
        ]);
        $curl->setHeaders([
            'Content-Type' => 'application/json; charset=UTF-8',
        ]);
//        must add this line
//         http://blog.csdn.net/kobejayandy/article/details/44761913
        $curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
        $response = $curl->get($url);

        if ($curl->errorCode === null) {
//                返回结果：
//{"errcode": 0,
//   "errmsg": "ok",
//   "userid": "zhangsan",
//   "name": "李四",
//   "department": [1, 2],
//   "order": [1, 2],
//   "position": "后台工程师",
//   "mobile": "15913215421",
//   "gender": "1",
//   "email": "zhangsan@gzdev.com",
//   "isleader": 1,
//   "avatar": "http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0",
//   "telephone": "020-123456",
//   "english_name": "jackzhang",
//   "extattr": {"attrs":[{"name":"爱好","value":"旅游"},{"name":"卡号","value":"1234567234"}]}，
//   "status": 1
//}
//                出错返回示例：
//
//{
//    "errcode": 40029,
//   "errmsg": "invalid code"
//}
            $responseArr = Json::decode($response, true);
            if ($responseArr['errcode'] != null){
                $exceptionStr = sprintf('errcode: %s, errmsg: %s', $responseArr['errcode'], $responseArr['errmsg']);
                throw new UserException($exceptionStr);
            }

            $newQywxUser = QywxHelper::arrayToQywxUser($responseArr);
            return $newQywxUser;
        } else {
            $exceptionStr = sprintf('errorCode: %s, errorText: %s', $curl->errorCode, $curl->errorText);
            throw new UserException($exceptionStr);
        }
    }


    /**
     * 得到组织列表
     * @param string|null $departmentId
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function getDepartments($departmentId = null, $successHandler = null){
        $action = Yii::t('app' , 'Find');
        $modelClass = Yii::t('app' , 'Department');

        $parent_qywx_id = '';
        if (!StringUtil::isNullOrWhiteSpace($departmentId)){
            $department = Department::findOne([
                'department_id' => $departmentId,
            ]);
            if ($department == null){
                return new ActionResult(false, CommonResources::OBJECT_NOT_FOUND($modelClass));
            }
            $parent_qywx_id = $department->department_qywx_id;
        }

        $url = $this->baseUrl . '/department/list';

        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'id' => $parent_qywx_id,
        ];
        return $this->getJson($url, $params, $action, $modelClass, $successHandler);
    }

    /**
     * 得到组织列表
     * @param string $departmentId 部门id
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function getUsersByDepartmentId($departmentId, $successHandler = null){
        $action = Yii::t('app' , 'Find');
        $modelClass = Yii::t('app' , 'User');

        $department = Department::findOne([
            'department_id' => $departmentId,
        ]);
        if ($department == null){
            return new ActionResult(false, CommonResources::OBJECT_NOT_FOUND($modelClass));
        }

        $url = $this->baseUrl . '/user/list';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'department_id' => $department->department_qywx_id,
            'fetch_child' => 'FETCH_CHILD',
        ];
        return $this->getJson($url, $params, $action, $modelClass, $successHandler);
    }

    /**
     * @param $jsonArr
    {
    "userid": "zhangsan",
    "name": "张三",
    "english_name": "jackzhang",
    "mobile": "15913215421",
    "department": [1, 2],
    "order":[10,40],
    "position": "产品经理",
    "gender": "1",
    "email": "zhangsan@gzdev.com",
    "isleader": 1,
    "enable":1,
    "avatar_mediaid": "2-G6nrLmr5EC3MNb_-zL1dDdzkd0p7cNliYu9V5w7o8K0",
    "telephone": "020-123456"，
    "extattr": {"attrs":[{"name":"爱好","value":"旅游"},{"name":"卡号","value":"1234567234"}]}
    }
     * @return ActionResult
     */
    public function createUser($jsonArr){
        $action = Yii::t('app' , 'Create');
        $modelClass = Yii::t('app' , 'User');

        $url = $this->baseUrl . '/user/create';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonArr, $action, $modelClass);
    }

    /**
     * @param $infoJson
     *     {
    "userid": "zhangsan",
    "name": "李四",
    "department": [1],
    "order": [10],
    "position": "后台工程师",
    "mobile": "15913215421",
    "gender": "1",
    "email": "zhangsan@gzdev.com",
    "isleader": 0,
    "enable": 1,
    "avatar_mediaid": "2-G6nrLmr5EC3MNb_-zL1dDdzkd0p7cNliYu9V5w7o8K0",
    "telephone": "020-123456",
    "english_name": "jackzhang",
    "extattr": {"attrs":[{"name":"爱好","value":"旅游"},{"name":"卡号","value":"1234567234"}]}
    }
     * @return ActionResult
     * @throws UserException
     */
    public function updateUser($infoJson){
        $action = Yii::t('app' , 'Create');
        $modelClass = Yii::t('app' , 'User');
        $url = $this->baseUrl . '/user/update';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $infoJson, $action, $modelClass);
    }

    /**
     * 删除用户
     * @param $userid string
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function deleteUser($userId, $successHandler = null){
        $action = Yii::t('app' , 'Delete');
        $modelClass = Yii::t('app' , 'User');

        $url = $this->baseUrl . '/user/delete';

        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'userid' => $userId,
        ];

        return $this->getJson($url, $params, $action, $modelClass, $successHandler);
    }


    /**批量删除用户
     * @param $jsonArr string
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function batchDeleteUser($jsonArr, $successHandler = null){
        $action = Yii::t('app' , 'Batch Delete');
        $modelClass = Yii::t('app' , 'User');

        $url = $this->baseUrl . '/user/batchdelete';

        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];

        return $this->postJson($url, $params, $jsonArr, $action, $modelClass, $successHandler);
    }

    /**
     * @param $url string
     * @param $params array
     * @param $action string
     * @param $modelClass string
     * @param callback|null $successHandler
     * @return ActionResult
     */
    protected function getJson($url, $params, $action, $modelClass, $successHandler = null){
//        $url = $this->baseUrl . '/user/delete';
//        $accessToken = QywxHelper::getAccessToken();

        $curl = new Curl();

        $curl->setOptions([
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => ["Content-type: application/json; charset=UTF-8"],
            CURLOPT_TIMEOUT        => 500,
        ]);
        $curl->setGetParams($params);

        $response = $curl->get($url);

        if ($curl->responseCode != 200){
            $exceptionStr = sprintf('responseCode: %s', $curl->responseCode);
            return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, $exceptionStr));
        }

        if ($curl->errorCode === null) {
//           {
//               "errcode": 0,
//               "errmsg": "deleted"
//            }
            $responseArr = json_decode($response, true);
            if ($responseArr['errcode'] != null && $responseArr['errcode'] > 0) {
                $exceptionStr = sprintf('errcode: %s, errmsg: %s', $responseArr['errcode'], $responseArr['errmsg']);
                return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, $exceptionStr));
            }
            if (isset($successHandler)){
                call_user_func_array($successHandler, $responseArr);
            }
            return new ActionResult(true, CommonResources::ACTION_SUCCESS_MSG($action, $modelClass));
        } else {
            $exceptionStr = sprintf('errorCode: %s, errorText: %s', $curl->errorCode, $curl->errorText);
            return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, $exceptionStr));
        }
    }

    /**
     * @param $url string
     * $param $params array
     * @param $body
     * @param $action
     * @param $modelClass
     * @param callback|null $successHandler
     * @return ActionResult
     */
    protected function postJson($url, $params, $body, $action, $modelClass, $successHandler = null){
        $curl = new Curl();

        if (StringUtil::isNullOrWhiteSpace($body)) {
            return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, 'Content is null'));
        }
        $curl->setOptions([
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => ["Content-type: application/json; charset=UTF-8"],
            CURLOPT_TIMEOUT        => 500,
        ]);
        $curl->setGetParams($params);
        $curl->setOption(
            CURLOPT_POSTFIELDS,
            $body
        );
        $response = $curl->post($url);

        if ($curl->responseCode != 200){
            $exceptionStr = sprintf('responseCode: %s', $curl->responseCode);
            return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, $exceptionStr));
        }

        if ($curl->errorCode === null) {
            $responseArr = json_decode($response, true);
            if ($responseArr['errcode'] != null && $responseArr['errcode'] > 0) {
                $exceptionStr = sprintf('errcode: %s, errmsg: %s', $responseArr['errcode'], $responseArr['errmsg']);
                return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, $exceptionStr));
            }
            if (isset($successHandler)){
                call_user_func_array($successHandler, $responseArr);
            }
            return new ActionResult(true, CommonResources::ACTION_SUCCESS_MSG($action, $modelClass));
        } else {
            $exceptionStr = sprintf('errorCode: %s, errorText: %s', $curl->errorCode, $curl->errorText);
            return new ActionResult(false, CommonResources::ACTION_FAIL_MSG($action, $modelClass, $exceptionStr));
        }
    }


    /**
     * @param $jsonArr
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function createDepartment($jsonStr, $successHandler = null){
        $action = Yii::t('app' , 'Create');
        $modelClass = Yii::t('app' , 'Department');

        $url = $this->baseUrl . '/department/create';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonStr, $action, $modelClass, $successHandler);
    }


    /**
     * @param $jsonStr string
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function updateDepartment($jsonStr, $successHandler = null){
        $action = Yii::t('app' , 'Update');
        $modelClass = Yii::t('app' , 'Department');

        $url = $this->baseUrl . '/department/update';
        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
        ];
        return $this->postJson($url, $params, $jsonStr, $action, $modelClass, $successHandler);
    }

    /**
     * @param $id string
     * @param callback|null $successHandler
     * @return ActionResult
     */
    public function deleteDepartment($id, $successHandler = null){
        $action = Yii::t('app' , 'Delete');
        $modelClass = Yii::t('app' , 'Department');

        $url = $this->baseUrl . '/department/delete';

        $params = [
            'access_token' => QywxHelper::getAccessTokenVal(),
            'id' => $id,
        ];

        return $this->getJson($url, $params, $action, $modelClass, $successHandler);
    }

}